using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;

namespace EasyXaf.Blazor.Splitters;

public partial class Splitter : IAsyncDisposable
{
    private ElementReference ContainerElementRef { get; set; }

    private DotNetObjectReference<Splitter> DotNetObjectRef { get; set; }

    private IJSObjectReference JsModule { get; set; }

    private string ContainerClassName
    {
        get
        {
            var classNames = new List<string>
            {
                "splitter-container",
                Orientation == SplitterOrientation.Horizontal ? "splitter-horizontal" : "splitter-vertical"
            };

            if (!string.IsNullOrWhiteSpace(ClassName))
            {
                classNames.AddRange(ClassName.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries));
            }

            return string.Join(" ", classNames);
        }
    }

    private string SplitterStyle
    {
        get
        {
            var styles = new List<string>
            {
                Orientation == SplitterOrientation.Horizontal ? $"height:{SplitterWidth}px" : $"width:{SplitterWidth}px",
                Orientation == SplitterOrientation.Horizontal ? $"cursor:n-resize" : $"cursor:e-resize"
            };

            if (!string.IsNullOrWhiteSpace(SplitterColor))
            {
                styles.Add($"background-color:{SplitterColor}");
            }

            return string.Join(";", styles);
        }
    }

    [Parameter]
    public SplitterOrientation Orientation { get; set; } = SplitterOrientation.Vertical;

    [Parameter]
    public string Panel1MinSize { get; set; } = "20px";

    [Parameter]
    public string Panel2MinSize { get; set; } = "20px";

    [Parameter]
    public string Panel1Size { get; set; }

    [Parameter]
    public string Panel2Size { get; set; }

    [Parameter]
    public RenderFragment Panel1 { get; set; }

    [Parameter]
    public RenderFragment Panel2 { get; set; }

    [Parameter]
    public int SplitterWidth { get; set; } = 4;

    [Parameter]
    public string SplitterColor { get; set; } = "#EEEEEE";

    [Parameter]
    public string ClassName { get; set; }

    [Parameter]
    public string Style { get; set; }

    [Parameter]
    public EventCallback OnResize { get; set; }

    [Inject]
    public IJSRuntime JSRuntime { get; set; }

    [JSInvokable]
    public async Task UpdatePanelSizeAsync(string panel1Size, string panel2Size)
    {
        Panel1Size = panel1Size;
        Panel2Size = panel2Size;
        StateHasChanged();
        await OnResize.InvokeAsync();
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await base.OnAfterRenderAsync(firstRender);

        if (firstRender)
        {
            var splitterParams = new SplitterParams
            {
                orientation = Orientation == SplitterOrientation.Horizontal ? "h" : "v",
                panel1MinSize = Panel1MinSize,
                panel2MinSize = Panel2MinSize,
                panel1Size = Panel1Size,
                panel2Size = Panel2Size,
                splitterWidth = SplitterWidth
            };
            var jsModuleFile = "./_content/EasyXaf.Blazor.Splitters/Splitter.razor.js";
            JsModule = await JSRuntime.InvokeAsync<IJSObjectReference>("import", jsModuleFile);
            DotNetObjectRef = DotNetObjectReference.Create(this);
            await JsModule.InvokeVoidAsync("init", ContainerElementRef, DotNetObjectRef, splitterParams);
        }
    }

    public async ValueTask DisposeAsync()
    {
        try
        {
            if (JsModule != null)
            {
                await JsModule.InvokeVoidAsync("dispose", ContainerElementRef);
            }
        }
        catch (JSDisconnectedException)
        {
        }

        if (JsModule != null)
        {
            await JsModule.DisposeAsync();
            JsModule = null;
        }

        DotNetObjectRef?.Dispose();
        DotNetObjectRef = null;

        GC.SuppressFinalize(this);
    }
}